/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "sk6812_spi.h"
/* Private define ------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/
SPI_HandleTypeDef Spi1Handle;

void Error_Handler(void);
void SystemClockConfig(void);
static void SPIConfig(void);

int main(void)
{
  /* 初始化所有外设，Flash接口，SysTick */
  HAL_Init();

  /* 系统时钟配置 */
  SystemClockConfig();
  SPIConfig();
  HAL_Delay(100); // 添加延时，等待电源稳定

  while (1)
  {
    // 演示不同的渐变效果
    static uint8_t effect_mode = 0;
    switch (effect_mode)
    {
      case 0:
        // 彩虹渐变效果
        rainbow_gradient(30, 50);
        break;
      case 1:
        // 统一颜色渐变效果
        uniform_gradient(30, 50); // 30 个中间过渡色，每步之间50ms延时
        break;
      case 2:
        // 彗星效果（尾长10，亮度255，延时30ms）
        comet_effect(10, 255, 30);
        break;
      case 3:
        // 红色掉落变绿堆积效果
        WS2812B_red_to_green_stack(50);//数值越大越慢
        break;
      case 4:
        // Red Wave纯红色波浪效果
        red_wave_effect(50);
        break;
      case 5:
        // Red Green Wave红绿波浪效果
        red_green_wave_effect(50);
        break;
      case 6:
        // Rainbow wave彩虹波浪效果
        rainbow_wave_effect(50);
        break;
      }

    // 切换效果模式
    effect_mode = (effect_mode + 1) % 7;
  }
}

static void SPIConfig(void)
{
  /* SPI配置 - 为sk6812/SK6812 */
  Spi1Handle.Instance = SPI1;
  Spi1Handle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4; /* 24MHz/4 = 6MHz */
  Spi1Handle.Init.Direction = SPI_DIRECTION_1LINE;             /* 单向传输，只发送 */
  Spi1Handle.Init.Mode = SPI_MODE_MASTER;                      /* 主机模式 */
  Spi1Handle.Init.DataSize = SPI_DATASIZE_8BIT;                /* 8位数据 */
  Spi1Handle.Init.CLKPolarity = SPI_POLARITY_LOW;              /* 时钟极性低 */
  Spi1Handle.Init.CLKPhase = SPI_PHASE_2EDGE;                  /* 第2个边沿采样 */
  Spi1Handle.Init.NSS = SPI_NSS_SOFT;                          /* 软件NSS */
  Spi1Handle.Init.FirstBit = SPI_FIRSTBIT_MSB;                 /* MSB先发送 */
  if (HAL_SPI_DeInit(&Spi1Handle) != HAL_OK)                   /* SPI反初始化 */
  {
    Error_Handler();
  }
  /* 初始化SPI - HAL_SPI_Init会自动调用HAL_SPI_MspInit配置GPIO */
  if (HAL_SPI_Init(&Spi1Handle) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
 * @brief  系统时钟配置函数
 * @param  无
 * @retval 无
 */
void SystemClockConfig(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /* 振荡器配置 */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_LSI; /* 选择振荡器HSE,HSI,LSI */
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;                                                                     /* 开启HSI */
  RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1;                                                                     /* HSI 1分频 */
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_24MHz;                                            /* 配置HSI时钟24MHz */
  RCC_OscInitStruct.HSEState = RCC_HSE_OFF;                                                                    /* 关闭HSE */
  /*RCC_OscInitStruct.HSEFreq = RCC_HSE_16_32MHz;*/
  RCC_OscInitStruct.LSIState = RCC_LSI_OFF; /* 关闭LSI */

  /* 配置振荡器 */
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /* 时钟源配置 */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1; /* 选择配置时钟 HCLK,SYSCLK,PCLK1 */
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;                                         /* 选择HSI作为系统时钟 */
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;                                             /* AHB时钟 1分频 */
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;                                              /* APB时钟 1分频 */
  /* 配置时钟源 */
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
 * @brief  错误执行函数
 * @param  无
 * @retval 无
 */
void Error_Handler(void)
{
  /* 无限循环 */
  while (1)
  {
  }
}

#ifdef USE_FUHAL_ASSERT
  /**
   * @brief  输出产生断言错误的源文件名及行号
   * @param  file：源文件名指针
   * @param  line：发生断言错误的行号
   * @retval 无
   */
  void assert_failed(uint8_t *file, uint32_t line)
  {
    /* 用户可以根据需要添加自己的打印信息,
       例如: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
    /* 无限循环 */
    while (1)
    {
    }
  }
#endif /* USE_FUHAL_ASSERT */

  /************************ (C) COPYRIGHT Puya *****END OF FILE****/
